package com.pignest.hotel.service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import com.pignest.hotel.beans.Card;
import com.pignest.hotel.beans.Living;
import com.pignest.hotel.beans.Member;
import com.pignest.hotel.beans.Room;
import com.pignest.hotel.beans.User;
import com.pignest.hotel.servlet.QueryServlet;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.system.L;


public class CardService extends BaseService {
	
	public Card getCard(String id) {
		return get(Card.class, id);
	}
	
	public void resetCard(String cardNumber) {
		Card card = getCardByCardNumber(cardNumber);
		if (card != null) {
			card.setType(Card.TYPE_NORMAL);
			card.setHolderName(null);
			card.setLockNumber(null);
			card.setExpireTime(null);
			update(card);
			L.update(card, "重置卡片");
		}
	}
	
	public void cancelCard(Card card) {
		if (card != null && StringUtils.isNotEmpty(card.getLockNumber())) {
			card.setLockNumber(null);
			card.setExpireTime(null);
			if (card.getType() == Card.TYPE_NORMAL)
				card.setHolderName(null);
			card.setLastUpdateTime(new Date());
			update(card);
			L.update(card, "销卡");
		}
	}
	
	/**
	 * @param serialNumber 卡序列号
	 * */
	public Card getCardBySerialNumber(String serialNumber) {
		if (serialNumber == null)
			return null;
		return get(Card.class, "serialNumber", serialNumber);
	}
	
	/** 可用的, 可重新授权的卡 */
	public Card getUsableCardBySerialNumber(String serialNumber) {
		Card card = getCardBySerialNumber(serialNumber);
		if (card == null || StringUtils.isEmpty(card.getCardNumber()))
			return null;
		if (card.isInUse())
			return null;
		return card;
	}

	/**
	 * 获取员工卡
	 * @param cardNumber 卡号
	 * */
	public Card getUserCard(String cardNumber) {
		Card card = getCardBySerialNumber(cardNumber);
		if (card == null || card.getType() != Card.TYPE_USER)
			return null;
		return card;
	}
	
	/**
	 * 获取会员卡
	 * @param cardNumber 卡号
	 * */
	public Card getMemberCard(String cardNumber) {
		Card card = getCardBySerialNumber(cardNumber);
		if (card == null || card.getType() != Card.TYPE_MEMBER)
			return null;
		return card;
	}
	
	/**
	 * 通过卡号获取卡
	 * @param cardNumber 卡号
	 * */
	public Card getCardByCardNumber(String cardNumber) {
		if (cardNumber == null)
			return null;
		return get(Card.class, "cardNumber", cardNumber);
	}
	
	/**
	 * 获取可用的员工卡
	 * @param serialNumber 卡序列号
	 * */
	public Card getUsableUserCard(String serialNumber) {
		Card card = getUserCard(serialNumber);
		if (card == null || !card.isEnable())
			return null;
		return card;
	}
	
	/**
	 * 获取可用的会员卡
	 * @param serialNumber 卡序列号
	 * */
	public Card getUsableMemberCard(String serialNumber) {
		Card card = getMemberCard(serialNumber);
		if (card == null || !card.isEnable())
			return null;
		return card;
	}
	/**
	 * 通过锁号获取卡
	 * */
	public List<Card> listCardsByLockNumber(String lockNumber) {
		if (lockNumber == null)
			return null;
		return query(Card.class, "lockNumber=?", new Object[] {lockNumber}, null);
	}
	
	public boolean grantCard(String serial, User user) {
		return grantCard(getCardBySerialNumber(serial), user);
	}
	
	public boolean grantCard(Card card, User user) {
		if (card == null || StringUtils.isEmpty(card.getCardNumber()))
			return false;
		card.setType(Card.TYPE_USER);
		card.setHolderName(user.getName());
		card.setLastUpdateTime(new Date());
		card.setLockNumber(null);
		update(card);
		user.setCardNumber(card.getCardNumber());
		update(user);
		return true;
	}
	
	public boolean grantCard(String serial, Member member) {
		return grantCard(getCardBySerialNumber(serial), member);
	}
	public boolean grantCard(Card card, Member member) {
		if (card == null || StringUtils.isEmpty(card.getCardNumber()))
			return false;
		card.setType(Card.TYPE_MEMBER);
		card.setHolderName(member.getName());
		card.setLastUpdateTime(new Date());
		card.setLockNumber(null);
		update(card);
		member.setCardNo(card.getCardNumber());
		update(member);
		return true;
	}
	
	public boolean grantCard(String serial, Room room, Date time) {
		return grantCard(getCardBySerialNumber(serial), room, time);
	}
	public boolean grantCard(Card card, Room room, Date time) {
		if (card == null || room.getLockNumber() == null)
			return false;
		if (card.getType() == Card.TYPE_NORMAL)
			card.setHolderName(room.getName());
		card.setLastUpdateTime(new Date());
		card.setLockNumber(room.getLockNumber());
		card.setExpireTime(time);
		update(card);
		return true;
	}
	
	public User getUserByCard(String serial) {
		Card card = getCardBySerialNumber(serial);
		if (card == null)
			return null;
		return get(User.class, "cardNumber", card.getCardNumber());
	}
	
	public Member getMemberByCard(String serial) {
		Card card = getCardBySerialNumber(serial);
		if (card == null)
			return null;
		return Services.getMemberService().getMemberByCardNumber(card.getCardNumber());
	}
	
	public Room getRoomByCard(String lockNumber) {
		return get(Room.class, "lockNumber", lockNumber);
	}
	
	public List<Card> getCardsByRoom() {
//		return query(Card.class, "holderName", values, types)
		return null;
	}
	
	///////////////////////////////////////////////////////////////////////////////////////////
	
	public String getCardUrl(HttpServletRequest request) throws UnsupportedEncodingException {
		String type = request.getParameter("type");
		String status = request.getParameter("status");
		String cardNumber = request.getParameter("cardNumber");
		String holderName = request.getParameter("holderName");
		String serialNumber = request.getParameter("serialNumber");
		String expireTime = request.getParameter("expireTime");
		
		StringBuilder url = new StringBuilder(request.getContextPath());
		url.append("/").append(QueryServlet.FILTER).append("/card");
		String enc = "UTF-8";
		char c = '?';
		if (StringUtils.isNotEmpty(type)) {
			url.append(c);
			c = '&';
			url.append("type=").append(type);
		}
		if (StringUtils.isNotEmpty(status)) {
			url.append(c);
			c = '&';
			url.append("status=").append(status);
		}
		if (StringUtils.isNotEmpty(cardNumber)) {
			url.append(c);
			c = '&';
			url.append("cardNumber=").append(cardNumber);
		}
		if (StringUtils.isNotEmpty(holderName)) {
			url.append(c);
			c = '&';
			url.append("holderName=").append(URLEncoder.encode(holderName, enc));
		}
		if (StringUtils.isNotEmpty(serialNumber)) {
			url.append(c);
			c = '&';
			url.append("serialNumber=").append(serialNumber);
		}
		if (StringUtils.isNotEmpty(expireTime)) {
			url.append(c);
			c = '&';
			url.append("expireTime=").append(expireTime);
		}
		return url.toString();
	}
	
	public int countCards(int type, Boolean enable, String cardNumber, String holderName, String serial, Date expire) {
		StringBuilder s = new StringBuilder();
		List<Object> values = new ArrayList<Object>();
		if (type >= 0) {
			s.append("type=?");
			values.add(type);
		}
		if (enable != null) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("enable=?");
			values.add(enable);
		}
		if (StringUtils.isNotEmpty(cardNumber)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("cardNumber like ?");
			values.add('%' + cardNumber + '%');
		}
		if (StringUtils.isNotEmpty(holderName)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("holderName like ?");
			values.add('%' + holderName + '%');
		}
		if (StringUtils.isNotEmpty(serial)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("serialNumber like ?");
			values.add('%' + serial + '%');
		}
		if (expire != null) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("expireTime>=?");
			values.add(expire);
		}
		return count(Card.class, s.toString(), values.toArray(new Object[values.size()]), null);
	}
	
	public List<Card> listCards(int type, Boolean enable, Boolean granted, String cardNumber, String holderName, String serial, Date expire,
			String orderBy, int pageSize, int pageIndex) {
		StringBuilder s = new StringBuilder();
		List<Object> values = new ArrayList<Object>();
		if (type >= 0) {
			s.append("type=?");
			values.add(type);
		}
		if (enable != null) {
//			int a = Utils.getInteger(enable, 0);
			if (s.length() > 0)
				s.append(" and ");
			s.append("enable=?");
			values.add(enable);
		}
		if (granted != null) {
			if (s.length() > 0)
				s.append(" and ");
			if (granted.booleanValue())
				s.append("lockNumber is not null");
			else
				s.append("lockNumber is null");
		}
		if (StringUtils.isNotEmpty(cardNumber)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("cardNumber like ?");
			values.add('%' + cardNumber + '%');
		}
		if (StringUtils.isNotEmpty(holderName)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("holderName like ?");
			values.add('%' + holderName + '%');
		}
		if (StringUtils.isNotEmpty(serial)) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("serialNumber like ?");
			values.add('%' + serial + '%');
		}
		if (expire != null) {
			if (s.length() > 0)
				s.append(" and ");
			s.append("expireTime>=?");
			values.add(expire);
		}
		if (StringUtils.isNotEmpty(orderBy)) {
			if (s.length() > 0)
				s.append(" ");
			s.append("order by ").append(orderBy);
		}
		return query(Card.class, s.toString(), pageSize, pageIndex, values.toArray(new Object[values.size()]), null);
	}
	 public boolean grantLivingCard(Living l,Card card)
	 {
		 try{
			 if(l==null)
				 return false;
			 this.update(l);
			 this.update(card);
			 return true;
		 }catch(Exception e)
		 {
			 return false;
		 }
	 }
}
